﻿#include "InIReader.h"

namespace AutoPatcherAdmin
{

    InIReader::InIReader(const std::string &fileName) : _contents(std::vector<std::string>()), _fileName(fileName)
    {

        try
        {
            if (FileSystem::fileExists(_fileName))
            {
                _contents.AddRange(File::ReadAllLines(_fileName));
            }
        }
        catch (...)
        {
        }
    }

    std::string InIReader::FindValue(const std::string &section, const std::string &key)
    {
        for (int a = 0; a < _contents.size(); a++)
        {
            if (_contents[a].compare("[" + section + "]") == 0)
            {
                for (int b = a + 1; b < _contents.size(); b++)
                {
                    if (StringHelper::split(_contents[b], '=')[0].compare(key) == 0)
                    {
                        return StringHelper::split(_contents[b], '=')[1];
                    }
                    else if (StringHelper::startsWith(_contents[b], "[") && StringHelper::endsWith(_contents[b], "]"))
                    {
                        return "";
                    }
                }
            }
        }
        return "";
    }

    int InIReader::FindIndex(const std::string &section, const std::string &key)
    {
        for (int a = 0; a < _contents.size(); a++)
        {
            if (_contents[a].compare("[" + section + "]") == 0)
            {
                for (int b = a + 1; b < _contents.size(); b++)
                {
                    if (StringHelper::split(_contents[b], '=')[0].compare(key) == 0)
                    {
                        return b;
                    }
                    else if (StringHelper::startsWith(_contents[b], "[") && StringHelper::endsWith(_contents[b], "]"))
                    {
                        _contents.Insert(b - 1, key + "=");
                        return b - 1;
                    }
                    else if (_contents.size() - 1 == b)
                    {
                        _contents.push_back(key + "=");
                        return _contents.size() - 1;
                    }
                }
            }
        }
        if (_contents.size() > 0)
        {
            _contents.push_back("");
        }

        _contents.push_back("[" + section + "]");
        _contents.push_back(key + "=");
        return _contents.size() - 1;
    }

    void InIReader::Save()
    {
        try
        {
            File::WriteAllLines(_fileName, _contents.ToArray());
        }
        catch (...)
        {
        }
    }

    bool InIReader::ReadBoolean(const std::string &section, const std::string &key, bool Default)
    {
        bool result;

        if (!bool::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    unsigned char InIReader::ReadByte(const std::string &section, const std::string &key, unsigned char Default)
    {
        unsigned char result;

        if (!unsigned char::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    signed char InIReader::ReadSByte(const std::string &section, const std::string &key, signed char Default)
    {
        signed char result;

        if (!signed char::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    unsigned short InIReader::ReadUInt16(const std::string &section, const std::string &key, unsigned short Default)
    {
        unsigned short result;

        if (!unsigned short::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    short InIReader::ReadInt16(const std::string &section, const std::string &key, short Default)
    {
        short result;

        if (!short::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    unsigned int InIReader::ReadUInt32(const std::string &section, const std::string &key, unsigned int Default)
    {
        unsigned int result;

        if (!unsigned int::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    int InIReader::ReadInt32(const std::string &section, const std::string &key, int Default)
    {
        int result;

        if (!int::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    unsigned long long InIReader::ReadUInt64(const std::string &section, const std::string &key, unsigned long long Default)
    {
        unsigned long long result;

        if (!unsigned long long::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    long long InIReader::ReadInt64(const std::string &section, const std::string &key, long long Default)
    {
        long long result;

        if (!long long::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    float InIReader::ReadSingle(const std::string &section, const std::string &key, float Default)
    {
        float result;

        if (!float::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    double InIReader::ReadDouble(const std::string &section, const std::string &key, double Default)
    {
        double result;

        if (!double::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    Decimal InIReader::ReadDecimal(const std::string &section, const std::string &key, Decimal Default)
    {
        Decimal result;

        if (!Decimal::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    std::string InIReader::ReadString(const std::string &section, const std::string &key, const std::string &Default)
    {
        std::string result = FindValue(section, key);

        if (result.empty())
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    char InIReader::ReadChar(const std::string &section, const std::string &key, char Default)
    {
        char result;

        if (!char::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }

        return result;
    }

    Point *InIReader::ReadPoint(const std::string &section, const std::string &key, Point *Default)
    {
        std::string temp = FindValue(section, key);
        int tempX, tempY;
        if (temp == "" || !int::TryParse(StringHelper::split(temp, ',')[0], tempX))
        {
            Write(section, key, Default);
            return Default;
        }
        if (!int::TryParse(StringHelper::split(temp, ',')[1], tempY))
        {
            Write(section, key, Default);
            return Default;
        }

        return new Point(tempX, tempY);
    }

    Size *InIReader::ReadSize(const std::string &section, const std::string &key, Size *Default)
    {
        std::string temp = FindValue(section, key);
        int tempX, tempY;
        if (!int::TryParse(StringHelper::split(temp, ',')[0], tempX))
        {
            Write(section, key, Default);
            return Default;
        }
        if (!int::TryParse(StringHelper::split(temp, ',')[1], tempY))
        {
            Write(section, key, Default);
            return Default;
        }

        return new Size(tempX, tempY);
    }

    TimeSpan InIReader::ReadTimeSpan(const std::string &section, const std::string &key, TimeSpan Default)
    {
        TimeSpan result;

        if (!TimeSpan::TryParse(FindValue(section, key), result))
        {
            result = Default;
            Write(section, key, Default);
        }


        return result;
    }

    void InIReader::Write(const std::string &section, const std::string &key, bool value)
    {
        _contents[FindIndex(section, key)] = key + "=" + StringHelper::toString(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, unsigned char value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, signed char value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, unsigned short value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, short value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, unsigned int value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, int value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, unsigned long long value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, long long value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, float value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, double value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, Decimal value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, const std::string &value)
    {
        _contents[FindIndex(section, key)] = key + "=" + value;
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, char value)
    {
        _contents[FindIndex(section, key)] = key + "=" + StringHelper::toString(value);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, Point *value)
    {
        _contents[FindIndex(section, key)] = key + "=" + value->X + "," + value->Y;
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, Size *value)
    {
        _contents[FindIndex(section, key)] = key + "=" + std::to_string(value->Width) + "," + std::to_string(value->Height);
        Save();
    }

    void InIReader::Write(const std::string &section, const std::string &key, TimeSpan value)
    {
        _contents[FindIndex(section, key)] = key + "=" + value;
        Save();
    }
}
